using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using WebapiTemplate.Domain.Entity;
using WebapiTemplate.Application.Common.Interface;

/// <summary>
/// 操作文件接口实现类
/// </summary>
namespace WebapiTemplate.Infrastructure.File
{
    public class FileService : IFileService
    {
        //定义文件信息保存表字段
        private readonly IRepository<FileLog> _fileLog;



        //依赖注入得到字段的真正实例
        public FileService(IRepository<FileLog> fileLog)
        {
            _fileLog = fileLog;
        }


        //接收并下载前端文件
        public async Task<dynamic> FileUpload(IFormCollection files)
        {
            if (files.Files.Count < 1)
            {
                return "文件为空";
            }
            //返回保存文件的详细信息
            List<dynamic> saveFilesInfo = new List<dynamic>();

            //手动一个存放图片的文件路径名称会需要时间对象
            var now = DateTime.Now;
            #region 以准确日期为文件取名
            /*
                var filePath = string.Format(
                    "/FilesUpload/{0}/{1}/{2}/",
                    now.ToString("yyyy"),
                    now.ToString("yyyyMM"),
                    now.ToString("yyyyMMdd")
                );
             */
            #endregion

            //获取当前项目根目录
            var webapiRootPath = Directory.GetCurrentDirectory();

            //生成存放文件的目录名称
            var fileRootPath = webapiRootPath + "/FilesUpload";

            //如果目录不存在就创建
            if (!Directory.Exists(fileRootPath))
            {
                Directory.CreateDirectory(fileRootPath);
            }

            //开始写入文件...
            try
            {
                foreach (var item in files.Files)
                {
                    if (item != null)
                    {
                        #region  文件过滤区
                        //定义允许通过的格式数组
                        string[] permittedExtensions = { ".txt", ".pdf", ".jpg", ".png"};

                        //拿到文件后缀
                        var ext = Path.GetExtension(item.FileName).ToLowerInvariant();

                        //过滤文件后缀
                        if (string.IsNullOrEmpty(ext) || !permittedExtensions.Contains(ext))
                        {
                            break;
                        }

                        //过滤文件大小
                        if (item.Length > 1024 * 1024 * 2) //限定2M
                        {
                            break;
                        }




                        #endregion 拆解文件信息
                        //原文件名
                        var OriginalName = item.FileName;
                        //原文件后缀
                        var Suffix = Path.GetExtension(OriginalName);
                        //文件类型
                        var FileType = item.ContentType;
                        //上传日期获取时间戳
                        var SaveDateTime = DateTime.Now.ToString("yyMMddhhmmssfff");
                        //文件字节大小
                        var FileSize = item.Length;


                        //创建保存文件的完整路径
                        var SaveFileName = Path.Combine(fileRootPath, SaveDateTime) + Suffix;



                        //在指定路径中创建文件流
                        using (var stream = System.IO.File.Create(SaveFileName))
                        {
                            //从当前item流中读取字节并将它们写入另一个fs文件流。两个流的位置都按复制的字节数前进
                            await item.CopyToAsync(stream);
                        }

                        //打包文件信息--用于上传数据库和返回给前端
                        FileLog objinfo = new FileLog();
                        //objinfo.HostUserId = HostUserId!=null? HostUserId : new Guid("a7f08bbe-d7a5-40e5-8ffb-139838273943");
                        objinfo.OriginalName = OriginalName;
                        objinfo.Suffix = Suffix;
                        objinfo.FileType = FileType;
                        objinfo.SaveDateTime = SaveDateTime;
                        objinfo.SaveFileName = SaveFileName;
                        objinfo.FileSize = FileSize;

                        //上传进数据库表
                       FileLog tableFile=  await _fileLog.AddAsync(objinfo);

                     
                        //上传成功的文件添加进信息集合中，已经包含刚刚生成的Id了
                        saveFilesInfo.Add(tableFile);
                    }
                    else
                    {
                        break;
                    }
                }

                //上传过程中若没有异常则返回后端处理文件的详细信息给前端
                return new { code = 1000, saveFilesInfo = saveFilesInfo };
            }
            //上传过程中产生异常
            catch (Exception ex)
            {
                return new { code = 400, msg = ex.ToString() };
            }
        }








        //根据前端传来的Id返回文件字节流给前端下载
        public async Task<FileContentResult> DolowdFile(Guid Id)
        {
            //在数据库中查找对应文件
         
            //可能是第一次找背景图片，也可能是通过HostUserId找头像
            //var file = new FileLog();//{00000000-0000-0000-0000-000000000000}
            // if(Id!=new Guid("00000000-0000-0000-0000-000000000000")){
              var  file = _fileLog.Table.FirstOrDefault(x => x.Id == Id);



            if (file != null)
            {
                //从数据库获取文件在后端项目中的真实路径(也可以在一开始接收前端文件时把文件字节流写入数据库，这样就直接把到文件字节流，还省去了后端本地多建文件夹)
                string path = Path.Combine("FilesUpload", file.SaveDateTime + file.Suffix); //可能为空，除非字段设置不为null

                //返回文件流拼接成的原文件
                using (var sw = new FileStream(path, FileMode.Open))
                {
                    var contenttype = file.FileType != null ? file.FileType : "";
                    var bytes = new byte[sw.Length];
                    await sw.ReadAsync(bytes, 0, bytes.Length);
                    sw.Close();
                    return new FileContentResult(bytes, contenttype);
                }

                #region 直接返回字节流的方法
                /*
                    //把文件转换为字节数组-再转为字符串
                    var buffer = System.IO.File.ReadAllBytes(path);
                    string bufferstr = System.Text.Encoding.Default.GetString(buffer);

                    //最后返回文件信息，包括文件名称、文件格式、文件字节流(转码为字符串后确实与原文件的编码一致)
                    return new
                    {
                        code = 1000,
                        msg = "获取字节流成!",
                        data = new
                        {
                            bufferstr = bufferstr,
                            filesuffix = file.Suffix,
                            OriginalName = file.OriginalName,
                            SaveDateTime = file.SaveDateTime
                        }
                    };
                 */
                #endregion

            }
            else
            {
                return new FileContentResult(new byte[0], "image/jpeg");
                //return new { code = 404, msg = "该文件不存在!", data = "" };
            }
        }

    }
}